package visual_db

import (
	"errors"
	"cgs-server/server"
	"cgs-server/server/base"
	"cgs-server/server/model"
	"go.mongodb.org/mongo-driver/bson"
)

type DbRepository interface {
	base.Repository
}

func NewMapRepository() DbRepository {
	return &dbRepository{
		RepositoryStruct: base.RepositoryStruct{
			CollectionName: server.CgsPortalDbCollectionName,
		},
	}
}

type dbRepository struct {
	base.RepositoryStruct
}

func (m *dbRepository) Find(mdl *model.DataUserModel) (interface{}, error) {
	if visualMap, ok := mdl.Data.(*Db); ok {
		if err := m.CheckDB(); err != nil {
			return nil, err
		}
		filter := bson.M{}
		visualMap.ResolveFilter(visualMap, mdl.User, &filter)
		opts := visualMap.ResolveOptions(mdl.Page)
		result := []*Db{}
		err := m.Mongo.FindMany(m.CollectionName, filter, &result, opts)
		return result, err
	} else {
		return nil, model.NewTypeError("VisualMap")
	}
}

func (m *dbRepository) Insert(mdl *model.DataUserModel) error {
	if visualMap, ok := mdl.Data.(*Db); ok {
		if err := m.CheckDB(); err != nil {
			return err
		}
		visualMap.ResolveEntity(visualMap, mdl.User)
		_, err := m.Mongo.InsertOne(m.CollectionName, visualMap)
		return err
	} else {
		return model.NewTypeError("VisualMap")
	}
}

func (m *dbRepository) Update(mdl *model.DataUserModel) error {
	if visualMap, ok := mdl.Data.(*Db); ok {
		if err := m.CheckDB(); err != nil {
			return err
		}
		filter := bson.M{
			"id": visualMap.Id,
		}
		visualMap.ResolveFilter(visualMap, mdl.User, &filter)

		updateOpt := bson.M{
			"password": visualMap.Password,
			"username": visualMap.Username,
			"remark": visualMap.Remark,
			"host": visualMap.Host,
			"port": visualMap.Port,
			"database": visualMap.Database,
		}
		if visualMap.Name != "" {
			updateOpt["name"] = visualMap.Name
		}
		if visualMap.DriverType != "" {
			updateOpt["driverType"] = visualMap.DriverType
		}
		if visualMap.Url != "" {
			updateOpt["url"] = visualMap.Url
		}
		visualMap.ResolveUpdateCondition(visualMap, mdl.User, &updateOpt)
		update := bson.M{"$set": updateOpt}

		_, err := m.Mongo.UpdateOne(m.CollectionName, filter, update)
		return err
	} else {
		return model.NewTypeError("VisualMap")
	}
}

func (m * dbRepository) Delete(mdl *model.DataUserModel) error {
	if visualMap, ok := mdl.Data.(*Db); ok {
		if err := m.CheckDB(); err != nil {
			return err
		}
		filter := bson.M{"id": visualMap.Id}
		visualMap.ResolveFilter(visualMap, mdl.User, &filter)
		_, err := m.Mongo.DeleteOne(m.CollectionName, filter)
		return err
	} else {
		return model.NewTypeError("VisualMap")
	}
}

func (m *dbRepository) FindOne(mdl *model.DataUserModel) (interface{}, error) {
	if visualMap, ok := mdl.Data.(*Db); ok {
		if err := m.CheckDB(); err != nil {
			return nil, err
		}
		filter := bson.M{"id": visualMap.Id}
		visualMap.ResolveFilter(visualMap, mdl.User, &filter)
		res := &Db{}
		find, err := m.Mongo.FindOne(m.CollectionName, filter, res)
		if !find {
			return nil, errors.New("not found")
		}
		return res, err
	} else {
		return nil, model.NewTypeError("VisualMap")
	}
}
